package com.whfc.iot.util;

import com.google.common.base.Preconditions;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import org.apache.commons.lang3.StringUtils;

/**
 * @Description:
 * @author: xugcheng
 * @version: 1.0
 * @date: 2019/7/17 10:04
 */
public class ByteUtil {

    /**
     * 3字节 转换 整形
     *
     * @param bytes
     * @return
     */
    public static int low3ByteToInt(byte[] bytes) {
        Preconditions.checkArgument(bytes.length >= 3, "数组长度不能小于3");
        return ((bytes[0] & 0x000000ff) << 16)
                | ((bytes[1] & 0x000000ff) << 8)
                | (bytes[2] & 0x000000ff);
    }

    /**
     * 3字节 转换 整形
     *
     * @param bytes
     * @return
     */
    public static int low3ByteToInt(int[] bytes) {
        Preconditions.checkArgument(bytes.length >= 3, "数组长度不能小于3");
        return ((bytes[0] & 0x000000ff) << 16) | ((bytes[1] & 0x000000ff) << 8) | (0x000000ff & bytes[2]);
    }

    public static long low6ByteToLong(byte[] bytes) {
        Preconditions.checkArgument(bytes.length >= 6, "数组长度不能小于6");
        return ((bytes[0] & 0x00000000ffL) << 40)
                | ((bytes[1] & 0x00000000ffL) << 32)
                | ((bytes[2] & 0x00000000ffL) << 24)
                | ((bytes[3] & 0x00000000ffL) << 16)
                | ((bytes[4] & 0x00000000ffL) << 8)
                | ((bytes[5] & 0x00000000ffL));
    }

    public static long low6ByteToLong(int[] bytes) {
        Preconditions.checkArgument(bytes.length >= 6, "数组长度不能小于6");
        return
                ((bytes[0] & 0x00000000ffL) << 40)
                        | ((bytes[1] & 0x00000000ffL) << 32)
                        | ((bytes[2] & 0x00000000ffL) << 24)
                        | ((bytes[3] & 0x00000000ffL) << 16)
                        | ((bytes[4] & 0x00000000ffL) << 8)
                        | ((bytes[5] & 0x00000000ffL));
    }


    public static byte[] extractLow3Byte(long value) {
        byte[] bytes = new byte[3];
        bytes[0] = (byte) ((value >> 16) & 0xFF);
        bytes[1] = (byte) ((value >> 8) & 0xFF);
        bytes[2] = (byte) (value & 0xFF);
        return bytes;
    }

    public static byte[] extractLow4Byte(long value) {
        byte[] bytes = new byte[4];
        bytes[0] = (byte) ((value >> 24) & 0xFF);
        bytes[1] = (byte) ((value >> 16) & 0xFF);
        bytes[2] = (byte) (value >> 8 & 0xFF);
        bytes[3] = (byte) (value & 0xFF);
        return bytes;
    }

    public static byte[] extractLow6Byte(long value) {
        byte[] bytes = new byte[6];
        bytes[0] = (byte) ((value >> 40) & 0xFF);
        bytes[1] = (byte) ((value >> 32) & 0xFF);
        bytes[2] = (byte) ((value >> 24) & 0xFF);
        bytes[3] = (byte) ((value >> 16) & 0xFF);
        bytes[4] = (byte) (value >> 8 & 0xFF);
        bytes[5] = (byte) (value & 0xFF);
        return bytes;
    }

    public static String toHexString(int data) {
        String hexStr = Integer.toHexString(data);
        StringBuffer buffer = new StringBuffer();
        if (hexStr.length() < 2) {
            for (int i = 0; i < 2 - hexStr.length(); i++) {
                buffer.append(0);
            }
        }
        buffer.append(hexStr);
        return buffer.toString();
    }

    public static int fromHexString(String hexStr) {
        if (StringUtils.isEmpty(hexStr)) {
            return 0;
        }
        int data = Integer.parseInt(hexStr, 16);
        return data;
    }

    /**
     * 字节数组转换成十六进制字符串
     *
     * @param dataArr
     * @return
     */
    public static String toHexString(int[] dataArr) {
        StringBuffer stringBuffer = new StringBuffer();
        for (int data : dataArr) {
            stringBuffer.append(toHexString(data));
        }
        return stringBuffer.toString();
    }


    /**
     * 提取bit
     *
     * @param value
     * @param bitIndex
     * @return
     */
    public static int getBit(int value, int bitIndex) {
        return (value >> bitIndex) & 0x00000001;
    }

    /**
     * 截取多个bit
     *
     * @param data
     * @param startIndex
     * @param endIndex
     * @return
     */
    public static int getBit(int data, int startIndex, int endIndex) {
        Preconditions.checkState(startIndex <= endIndex);
        String bitStr = getBitStr(data, startIndex, endIndex);
        return Integer.parseInt(bitStr, 2);
    }

    /**
     * 提取多个bit字符串
     *
     * @param data
     * @param startIndex
     * @param endIndex
     * @return
     */
    private static String getBitStr(int data, int startIndex, int endIndex) {
        StringBuffer str = new StringBuffer();
        for (int i = startIndex; i <= endIndex; i++) {
            str.append(ByteUtil.getBit(data, i));
        }
        return str.reverse().toString();
    }

    public static void main(String[] args) {

//        byte[] bytes = ByteUtil.extractLow6Byte(4751L);
//        long data = ByteUtil.low6ByteToLong(bytes);
//
//        ByteBuf buf = Unpooled.copiedBuffer(bytes);
//        System.out.println(ByteBufUtil.prettyHexDump(buf));
//
//        System.out.println(data);

//        byte[] bytes = new byte[]{
//                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
//        };

        ByteBuf buf = Unpooled.buffer(8);
        buf.writeByte(0x00);
        buf.writeByte(0x01);
        buf.writeByte(0x02);
        buf.writeByte(0x03);
        buf.writeByte(0xF0);
        buf.writeByte(0xF1);
        buf.writeByte(0xFE);
        buf.writeByte(0xFF);

        System.out.println(ByteBufUtil.prettyHexDump(buf));

        int[] bytes = new int[8];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = buf.readUnsignedByte();
        }

        System.out.println(ByteUtil.toHexString(bytes));
        System.out.println(ByteUtil.toHexString(0xFF));

    }
}
